package no.ntnu.fp.gui.mainFrame;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Locale;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import no.ntnu.fp.client.Client;
import no.ntnu.fp.gui.EventDispatcher;
import no.ntnu.fp.gui.calendar.DayPanel;
import no.ntnu.fp.gui.events.CancelMeetingEvent;
import no.ntnu.fp.gui.events.DeleteAppointmentEvent;
import no.ntnu.fp.gui.events.GuiEvent;
import no.ntnu.fp.model.Appointment;
import no.ntnu.fp.model.DialogModel;
import no.ntnu.fp.model.Employee;
import no.ntnu.fp.model.Meeting;
import no.ntnu.fp.model.DialogModel.StateOfDialog;
import no.ntnu.fp.utils.Participant;

/**
 * This is the information field below the main calendar in the main view.
 * @author Caroline
 *
 */

@SuppressWarnings("serial")
public class InfoField extends JPanel implements PropertyChangeListener{
	private JLabel roomLabel, tid, dato, tittel, descriptionLabel, 
	meetingLeaderLabel, meetingLeader;
	private JPanel dltgrList;
	private JButton deleteButton, changeButton;
	private Appointment currentAppointment;
	private JScrollPane scp;

	public void setupUi() { 
		GridBagLayout gbl = new GridBagLayout();
		this.setLayout(gbl);
		Font lgLabelType = new Font("Tahoma", Font.BOLD, 14);
		Font smLabelType = new Font("Tahoma", Font.PLAIN, 12);

		GridBagConstraints c = new GridBagConstraints();
		c.insets = new Insets(2, 15, 2, 15);

		c.gridx = 0;
		c.gridy = 0;
		JLabel stedLabel = new JLabel("Sted:");
		stedLabel.setFont(lgLabelType);
		add(stedLabel, c);

		c.gridy = 1;
		roomLabel = new JLabel("");
		roomLabel.setFont(smLabelType);
		add(roomLabel, c);

		c.gridy = 2;
		JLabel tidLabel = new JLabel("Tid og dato:");
		tidLabel.setFont(lgLabelType);
		add(tidLabel, c);

		c.gridy = 3;
		tid = new JLabel("");
		tid.setFont(smLabelType);
		add(tid, c);

		c.gridy = 4;
		dato = new JLabel("");
		dato.setFont(smLabelType);
		add(dato, c);

		c.gridx = 1;
		c.gridy = 0;
		JLabel tittelLabel = new JLabel("Tittel:");
		tittelLabel.setFont(lgLabelType);
		add(tittelLabel, c);

		c.gridy = 1;
		tittel = new JLabel("");
		tittel.setFont(smLabelType);
		add(tittel, c);

		c.gridy = 2;
		JLabel descLabel = new JLabel("Beskrivelse:");
		descLabel.setFont(lgLabelType);
		add(descLabel, c);

		c.gridy = 3;
		descriptionLabel = new JLabel("");
		descriptionLabel.setFont(smLabelType);
		add(descriptionLabel, c);

		c.gridx = 2;
		c.gridy = 0;
		meetingLeaderLabel = new JLabel("<html>M&oslash;teleder:<html>");
		meetingLeaderLabel.setFont(lgLabelType);
		add(meetingLeaderLabel, c);

		c.gridy = 1;
		meetingLeader = new JLabel("");
		meetingLeader.setFont(smLabelType);
		add(meetingLeader, c);

		c.gridx = 3;
		c.gridy = 0;
		c.gridheight = 4;
		c.ipady = 100;
		c.ipadx = 50;
		JPanel deltakere = new JPanel();
		BoxLayout bl = new BoxLayout(deltakere, BoxLayout.Y_AXIS);
		deltakere.setLayout(bl);
		JLabel dltgrLabel = new JLabel("Deltakere:");
		dltgrLabel.setFont(lgLabelType);
		deltakere.add(dltgrLabel);

		dltgrList = new JPanel(); //This list needs a model. Not sure about the scrollpane
		dltgrList.setLayout(new BoxLayout(dltgrList, BoxLayout.Y_AXIS));
		scp = new JScrollPane(dltgrList);
		deltakere.add(scp);
		add(deltakere, c);

		deleteButton = new JButton("Fjern");
		deleteButton.addActionListener(new DeleteButtonAction());
		changeButton = new JButton("Endre");
		changeButton.addActionListener(new ChangeButtonAction());
		c.ipadx = 0;
		c.ipady = 0;
		c.gridx = 4;
		c.gridy = 1;
		c.gridheight = 1;
		c.gridwidth = 1;
		c.insets = new Insets(3, 150, 3, 10);
		add(changeButton, c);
		c.gridy = 2;
		add(deleteButton, c);
	}
	public InfoField(){
		this.setupUi();
		this.setPreferredSize(new Dimension(500, 200));
		this.currentAppointment = null;
		changeButton.setEnabled(false);
	}

	public void setAppointment(Appointment appointment){
		this.currentAppointment = appointment;
		roomLabel.setText((appointment.getRoom() == null)? 
				appointment.getPlace() : appointment.getRoom().getName());
		DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.GERMAN);
		tid.setText(format.format(appointment.getStartTime()) + " - " + 
				format.format(appointment.getEndTime()));
		format = DateFormat.getDateInstance(DateFormat.FULL);
		dato.setText(format.format(appointment.getDate()));
		tittel.setText(appointment.getTitle());
		if(appointment.getDescription() != null && appointment.getDescription().length() >= 20){
			descriptionLabel.setText(appointment.getDescription().substring(0, 17) + "...");
		}else{
			descriptionLabel.setText(appointment.getDescription());
		}
		meetingLeader.setText(appointment.getEmployee().getName());
		dltgrList.setVisible(false);
		meetingLeaderLabel.setVisible(false);
		meetingLeader.setVisible(false);
		deleteButton.setText("Fjern avtale");

		if(!appointment.getEmployee().equals(Client.getEmployee())){
			deleteButton.setEnabled(false);
			changeButton.setEnabled(true);
			changeButton.setText("Vis avtale");
		}else{
			deleteButton.setEnabled(true);
			changeButton.setEnabled(true);
			changeButton.setText("Endre avtale");
		}
	}

	public void setMeeting(Meeting meeting){
		this.setAppointment(meeting);
		for(Participant p: meeting.getParticipants()){
			dltgrList.add(new EmployeeButton(p.getEmployee()));
		}
		dltgrList.validate();
		dltgrList.setVisible(true);
		scp.setVisible(true);
		scp.validate();
		meetingLeaderLabel.setVisible(true);
		meetingLeader.setVisible(true);
		deleteButton.setText("Avlys møte");

		deleteButton.setEnabled(true);
		ArrayList<Employee> emps = new ArrayList<Employee>();
		for(Participant p : meeting.getParticipants()){
			if(p.isAttending() != null && p.isAttending()){
				emps.add(p.getEmployee());
			}
		}
		changeButton.setEnabled(true);
		if(!meeting.getEmployee().equals(Client.getEmployee())){
			changeButton.setText("Møte informasjon");
			if(emps.contains(Client.getEmployee())){
				deleteButton.setText("Meld avbud");
			}else{
				deleteButton.setEnabled(false);
			}
		} else{
			changeButton.setText("Endre møte");
		}
	}
	public void clear(){
		this.currentAppointment = null;
		roomLabel.setText("");
		tid.setText("");
		dato.setText("");
		tittel.setText("");
		descriptionLabel.setText("");
		//meetingLeader.setText(appointment.getEmployee().getName());
		scp.setVisible(false);
		dltgrList.removeAll();
		dltgrList.validate();
		scp.validate();
		meetingLeaderLabel.setVisible(false);
		meetingLeader.setVisible(false);
		deleteButton.setEnabled(false);
		changeButton.setEnabled(false);
		deleteButton.setText("Fjern");
		changeButton.setText("Endre");
	}

	private final class EmployeeButton extends JButton implements ActionListener{
		private final Employee employee;
		public EmployeeButton(Employee employee){
			this.employee = employee;
			this.setText(employee.getName());
			this.addActionListener(this);
			this.setToolTipText(employee.getName());
			this.setPreferredSize(new Dimension(150, 20));
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			if(!employee.equals(Client.getEmployee())){
				Object[] questionButtonText = {"Importer", "Ikke importer"};
				int answer = JOptionPane.showOptionDialog(InfoField.this.getParent(), 
						"�nsker du � importere " + this.getText() + " sin kalender?", 
						"Importer kalender", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, 
						null, questionButtonText, questionButtonText[0]);
				if(answer == JOptionPane.YES_OPTION){
					Toolbar.getInstance().addEmployeeCalendar(employee);
				}
			}else{
				JOptionPane.showMessageDialog(InfoField.this.getParent(),
						"Du kan ikke importere din egen kalender", "Liten vits egentlig", 
						JOptionPane.INFORMATION_MESSAGE);
			}
		}
	}
	private final class ChangeButtonAction implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent e) {
			if(currentAppointment != null){
				if(currentAppointment instanceof Meeting){
					if(currentAppointment.getEmployee().equals(Client.getEmployee())){
						DialogModel.getInstance().setMeeting(
								StateOfDialog.OWN_MEETING, (Meeting) currentAppointment);
					}else{
						DialogModel.getInstance().setAppointment(
								StateOfDialog.MEETING, currentAppointment);
					}
				}else{
					if(currentAppointment.getEmployee().equals(Client.getEmployee())){
						DialogModel.getInstance().setAppointment(
								StateOfDialog.APPOINTMENT, currentAppointment);
					}else{
						DialogModel.getInstance().setAppointment(
								StateOfDialog.MEETING, currentAppointment);
					}
				}
				InfoField.this.clear();
			}else{
				throw new IllegalStateException("Appointment is null");
			}
		}
	}
	private final class DeleteButtonAction implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			String message;
			String[] options = {"Fjern avtale", "Ikke fjern"};
			Appointment selectedAppointment = DayPanel.getSelectedAppointment();
			if(selectedAppointment instanceof Meeting){
				if(selectedAppointment.getEmployee().equals(Client.getEmployee())){
					message = "�nsker du � avlyse dette m�te? En melding vil bli sendt ut" +
					" om at m�te er blitt avlyst";
					options[0] = "Avlys m�te og send beskjed";
				}else{
					message = "Ønsker du å melde avbud på dette møte?";
					options[0] = "Meld avbud";
					options[1] = "Ikke meld avbud";
				}
			}else{
				message = "�nsker du � fjerne denne avtalen?";
			}
			int answer = JOptionPane.showOptionDialog(InfoField.this.getParent(), 
					message, "Fjern?", JOptionPane.YES_NO_OPTION, 
					JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
			if(answer == JOptionPane.YES_OPTION){
				GuiEvent evt;
				if(selectedAppointment instanceof Meeting){
					evt = new CancelMeetingEvent(this, 
							(Meeting) selectedAppointment, Client.getEmployee());
				}else{
					evt = new DeleteAppointmentEvent(this, 
							selectedAppointment);
				}
				InfoField.this.clear();
				EventDispatcher.dispatchEvent(evt);
			}
		}
	}
	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		Appointment app = (Appointment) evt.getNewValue();
		clear();			
		if(app != null){
			if(app instanceof Meeting){
				InfoField.this.setMeeting((Meeting) app);
			}else{
				InfoField.this.setAppointment(app);
			}
		}
	}
}
